package com.wdb.common.configurer.httpclient;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
@ConditionalOnClass({
        EntityUtils.class,
        RequestConfig.class,
        HttpClientBuilder.class,
        CloseableHttpClient.class,
        PoolingHttpClientConnectionManager.class})
@EnableConfigurationProperties(HttpClientProperties.class)
public class HttpClientConfigurer {
    @Resource
    private HttpClientProperties properties;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Bean
    public HttpClientConnectionManager httpClientConnectionManager() {
        PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();

        manager.setMaxTotal(properties.getMaxTotal());
        manager.setDefaultMaxPerRoute(properties.getDefaultMaxPerRoute());
        manager.setValidateAfterInactivity(properties.getValidateAfterInactivity());

        return manager;
    }

    @Bean
    public HttpClientBuilder httpClientBuilder(HttpClientConnectionManager manager) {
        HttpClientBuilder builder = HttpClientBuilder.create();

        builder.setConnectionManager(manager);

        return builder;
    }

    @Bean
    public CloseableHttpClient closeableHttpClient(HttpClientBuilder builder) {
        return builder.build();
    }

    @Bean
    public RequestConfig requestConfig() {
        return RequestConfig.custom()
                .setSocketTimeout(properties.getSocketTimeout())
                .setConnectTimeout(properties.getConnectTimeout())
                .setConnectionRequestTimeout(properties.getConnectionRequestTimeout())
                .build();
    }

    @Bean
    public HttpHandler httpHandler(RequestConfig requestConfig, HttpClient httpClient) {
        HttpHandlerSupport handler = new HttpHandlerSupport();
        handler.setHttpClient(httpClient);
        handler.setRequestConfig(requestConfig);

        if (logger.isDebugEnabled()) {
            logger.info("{}", "added http client pool");
        }

        return handler;
    }
}
